package gov.kqqzyyy.monkey.pharmacyscreen.code.mytools;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.view.KeyEvent;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.socks.library.KLog;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;

import gov.kqqzyyy.monkey.pharmacyscreen.code.adapter.MyGridViewAdapter;
import gov.kqqzyyy.monkey.pharmacyscreen.code.adapter.MyHJBRAdapter;
import gov.kqqzyyy.monkey.pharmacyscreen.code.broadcast.DownLoadReceiver;
import gov.kqqzyyy.monkey.pharmacyscreen.code.broadcast.UpdateReceiver;
import gov.kqqzyyy.monkey.pharmacyscreen.code.object.HJBR;
import gov.kqqzyyy.monkey.pharmacyscreen.code.object.Patient;
import gov.kqqzyyy.monkey.pharmacyscreen.code.service.UpdateService;
import gov.kqqzyyy.monkey.pharmacyscreen.code.ui.FragmentPreferences;
import gov.kqqzyyy.monkey.pharmacyscreen.code.ui.SplashActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Created by Monkey on 2017/10/21.
 * 自定义基Activity
 */

@SuppressLint("Registered")
public class PharmacyWindowBaseActivity extends AppCompatActivity {

    private TextView timeTextView;
    private GridView mainGridView;
    private GridView kljGridView;
    private MyGridViewAdapter gridViewAdapter;
    private MyGridViewAdapter kljGridViewAdapter;

    private ProgressDialogFragment progressDialogFragment;

    private MyApplication myApplication;
    private SharedPreferences mSharedPreferences;

    private Timer clockTimer;
    private Timer scrollTimer;
    private MyHandler handler;
    private DownLoadReceiver downLoadReceiver;
    private UpdateReceiver updateReceiver;
    private Intent serviceIntent;

    private int textSize = 40;

    private List<Patient> mResultList;
    private List<HJBR> mHJBRList;

    Date localDateTime;
    String showDate;
    private boolean moveToBottom = true;
    private boolean isUploading = false;
    private Thread ftpThread;

    private Call<String> systemTimeCall;
    private Call<String> patientsCall;
    private Call<String> hjbrCall;
//    private boolean changeTypeFace;

    private UploadListener uploadListener;

    public void setTimeDelay(int timeDelay) {
        getMyApplication().setTimeDelay(timeDelay);
    }

    public String getShowDate() {
        return showDate;
    }

    public void doGetServerTime() {
        systemTimeCall = MyServiceUtil.getSystemTimeCall();
        Callback<String> callback = new Callback<String>() {
            @Override
            public void onResponse(@NonNull Call<String> call, Response<String> response) {
                String result = response.body();
                if (result != null) {
                    result = result.replace("\"", "");
                    try {
                        Date serverDate = myApplication.getSdfDateTime().parse(result);
                        long deteDelta = Objects.requireNonNull(serverDate).getTime() - new Date(System.currentTimeMillis()).getTime();
                        myApplication.setDeteDelta(deteDelta);
                        Toast.makeText(getApplicationContext(), "系统时间已同步！", Toast.LENGTH_SHORT).show();
                        doSetQYSJ();
                    } catch (ParseException e) {
                        e.printStackTrace();
                        Toast.makeText(getApplicationContext(), "获取系统时间格式化出错！", Toast.LENGTH_SHORT).show();
                    }
                }
            }

            @Override
            public void onFailure(@NonNull Call<String> call, Throwable t) {
                Toast.makeText(getApplicationContext(), "获取服务器时间出错：" + t.toString(), Toast.LENGTH_SHORT).show();
            }
        };
        systemTimeCall.enqueue(callback);

    }

    public void doSetQYSJ() {

    }

    public void setChangeTypeFace(boolean changeTypeFace) {
//        this.changeTypeFace = changeTypeFace;
        if (gridViewAdapter != null) {
            gridViewAdapter.setChangeTypeFace(changeTypeFace);
        }
    }

    public void doGetPatients(int yfsb, String cksb, final boolean isGettingHJBR) {
        patientsCall = MyServiceUtil.getPatientsCall(yfsb, cksb);
        Callback<String> callback = new Callback<String>() {
            @Override
            public void onResponse(@NonNull Call<String> call, Response<String> response) {
                String result = response.body();
                if (result != null && !result.equals("[]")) {
                    Gson gson = new Gson();
                    try {
                        mResultList = gson.fromJson(result, new TypeToken<List<Patient>>() {
                        }.getType());
                    } catch (Exception e) {
                        KLog.d("APE", e);
                    }
                } else {
                    mResultList = null;
                }
                if (isGettingHJBR) {
                    doGetHJBR();
                } else {
                    doFilterData();
                }
            }

            @Override
            public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
                mResultList = null;
                mHJBRList = null;
//                Toast.makeText(getApplicationContext(), "获取病人数据失败：" + t.toString(), Toast.LENGTH_SHORT).show();
                doFilterData();
            }
        };
        patientsCall.enqueue(callback);
    }

    public void doGetHJBR() {
        hjbrCall = MyServiceUtil.getAllHJBR();
        Callback<String> callback = new Callback<String>() {
            @Override
            public void onResponse(@NonNull Call<String> call, Response<String> response) {
                String result = response.body();
                if (result != null && !result.equals("[]")) {
                    Gson gson = new Gson();
                    mHJBRList = gson.fromJson(result, new TypeToken<List<HJBR>>() {
                    }.getType());
                } else {
                    mHJBRList = null;
                }
                doFilterData();
            }

            @Override
            public void onFailure(@NonNull Call<String> call, @NonNull Throwable t) {
                mHJBRList = null;
//                Toast.makeText(getApplicationContext(), "获取呼叫病人数据失败：" + t.getMessage(), Toast.LENGTH_SHORT).show();
                doFilterData();
            }
        };
        hjbrCall.enqueue(callback);

    }

    public void setTimeTextView(TextView timeTextView) {
        this.timeTextView = timeTextView;
    }

    public void setMainGridView(GridView mainGridView) {
        this.mainGridView = mainGridView;
        gridViewAdapter.setTextSize(textSize);
        mainGridView.setAdapter(gridViewAdapter);
    }

    public void setKljGridView(GridView kljGridView) {
        this.kljGridView = kljGridView;
        kljGridViewAdapter.setTextSize(textSize);
        kljGridView.setAdapter(kljGridViewAdapter);
    }

    public void setTextSize(int textSize) {
        this.textSize = textSize;
    }

    public void setColumnNum(int columnNum) {
        if (mainGridView != null) {
            mainGridView.setNumColumns(columnNum);
            gridViewAdapter.notifyDataSetChanged();
        }
        if (kljGridView != null) {
            kljGridView.setNumColumns(columnNum);
            kljGridViewAdapter.notifyDataSetChanged();
        }
    }

    public MyApplication getMyApplication() {
        return myApplication;
    }

    public List<Patient> getmResultList() {
        return mResultList;
    }

    public List<HJBR> getmHJBRList() {
        return mHJBRList;
    }

    public SharedPreferences getmSharedPreferences() {
        return mSharedPreferences;
    }

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        handler = new MyHandler(this);
        myApplication = (MyApplication) getApplication();
        mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        gridViewAdapter = new MyGridViewAdapter(this);
        kljGridViewAdapter = new MyGridViewAdapter(this);

        downLoadReceiver = new DownLoadReceiver(this);
        IntentFilter downLoadFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        registerReceiver(downLoadReceiver, downLoadFilter);
        updateReceiver = new UpdateReceiver(this);
        IntentFilter updateFilter = new IntentFilter("updatebroadcast");
        registerReceiver(updateReceiver, updateFilter);
        IntentFilter restartFilter = new IntentFilter();
        restartFilter.addAction(Intent.ACTION_TIME_TICK);
        registerReceiver(SystemTimeReceiver, restartFilter);
        serviceIntent = new Intent(getApplicationContext(), UpdateService.class);
        uploadListener = (currentStep, uploadSize, file) -> {
            KLog.d("APE", currentStep);
            switch (currentStep) {
                case FtpUtil.FTP_UPLOAD_SUCCESS:
                    KLog.d("APE", file.getName() + " 上传完成");
                    break;
                case FtpUtil.FTP_UPLOAD_LOADING:
                    long fize = file.length();
                    float num = (float) uploadSize / (float) fize;
                    int result = (int) (num * 100);
                    KLog.d("APE", "downloading :" + result);
                    break;
                case FtpUtil.FTP_DISCONNECT_SUCCESS:
                    stopUploadThread();
                    break;
            }
        };
    }

    public void setmShowList(List<Patient> list) {
        if (list != null) {
            gridViewAdapter.setPatientList(list);
        }
    }

    protected void setKljList(List<Patient> list) {
        if (list != null) {
            kljGridViewAdapter.setPatientList(list);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        doSetVersion();

        startService(serviceIntent);
        if (clockTimer != null) {
            clockTimer.cancel();
            clockTimer = null;
        }
        clockTimer = new Timer();
        clockTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 0x11;
                handler.sendMessage(message);
            }
        }, 1, 1000);
        if (scrollTimer != null) {
            scrollTimer.cancel();
            scrollTimer = null;
        }
        scrollTimer = new Timer();
        scrollTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 0x31;
                handler.sendMessage(message);
            }
        }, 5000, 5000);
        deleteOldApk();
    }

    public void doStartService() {
        startService(serviceIntent);
    }

    private void deleteOldApk() {
        File fileCache = new File(String.valueOf(getApplicationContext().getExternalCacheDir()));
        String path = fileCache.getParentFile() + "/files/" + Environment.DIRECTORY_DOWNLOADS;
        File fileDir = new File(path);
        if (fileDir.isDirectory()) {
            File[] files = fileDir.listFiles();
            if (Objects.requireNonNull(files).length > 0) {
                for (File file : files
                ) {
                    if (file.exists()) {
                        if (file.delete()) {
                            KLog.d("APE", file.getName() + "删除成功！");
                        } else {
                            KLog.d("APE", file.getName() + "删除失败！");
                        }
                    }
                }
            }
        }
    }

    private static class MyHandler extends Handler {
        WeakReference<PharmacyWindowBaseActivity> mActivity;

        MyHandler(PharmacyWindowBaseActivity activity) {
            mActivity = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            PharmacyWindowBaseActivity activity = mActivity.get();
            switch (msg.what) {
                case 0x11://
                    activity.setClock();
                    break;
                case 0x31:
                    activity.doRollingGridView();
                    break;
            }
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Toast.makeText(getApplicationContext(), "key：" + keyCode, Toast.LENGTH_SHORT).show();
        switch (keyCode) {
            case KeyEvent.KEYCODE_MENU:
                Intent intent = new Intent(getApplicationContext(), FragmentPreferences.class);
                startActivity(intent);
                finish();
                return true;
            case KeyEvent.KEYCODE_BACK:
                Intent intent1 = new Intent(getApplicationContext(), SplashActivity.class);
                startActivity(intent1);
                return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onStop() {
        super.onStop();
        stopUploadThread();
        stopService(serviceIntent);
        if (clockTimer != null) {
            clockTimer.cancel();
            clockTimer = null;
        }
        if (scrollTimer != null) {
            scrollTimer.cancel();
            scrollTimer = null;
        }
        if (systemTimeCall != null && systemTimeCall.isExecuted()) {
            systemTimeCall.cancel();
        }
        if (patientsCall != null && patientsCall.isExecuted()) {
            patientsCall.cancel();
        }
        if (hjbrCall != null && hjbrCall.isExecuted()) {
            hjbrCall.cancel();
        }
        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(downLoadReceiver);
        unregisterReceiver(updateReceiver);
        unregisterReceiver(SystemTimeReceiver);
        System.gc();
    }

    protected void onBindUI() {
    }

    public void cancelProgressDialog() {
        if (progressDialogFragment != null && progressDialogFragment.getDialog() != null) {
            progressDialogFragment.getDialog().dismiss();
        }
    }

    public void showProgressDialog(String message) {
        cancelProgressDialog();
        progressDialogFragment = new ProgressDialogFragment();
        progressDialogFragment.setMessage(message);
        progressDialogFragment.show(getFragmentManager(), "downLoading");
    }

    //显示时间
    protected void setClock() {
        if (timeTextView != null) {
            localDateTime = new Date(System.currentTimeMillis());
            localDateTime.setTime(localDateTime.getTime() + myApplication.getDeteDelta());
            showDate = myApplication.getSdfWeekDay().format(localDateTime);
            String text = showDate.substring(0, 11) + "\n" + showDate.substring(11, 14) + " " + showDate.substring(14);
            timeTextView.setText(text);
        }
    }

    public void doSetVersion() {

    }

    // 更新提示对话框
    public void showUpdateDialog(int newVerCode, String newVerName, String updateInfo) {
        cancelProgressDialog();
        String message = "";
        final Intent intent = new Intent("toUpdateService");
        message += "发现新版本：" + newVerName + "\n";
        message += "版本号：" + newVerCode + "\n";
        message += "更新内容：" + updateInfo + "\n";
        message += "是否更新？";
        Dialog dialog = new AlertDialog.Builder(this)
                .setTitle("软件更新")
                .setMessage(message)
                .setCancelable(false)
                .setPositiveButton("确定", (dialogInterface, i) -> {
                    intent.putExtra("toservice", 0x11);
                    sendBroadcast(intent);
                    dialogInterface.dismiss();
                    showProgressDialog("下载中");
                })
                .setNegativeButton("取消", (dialogInterface, i) -> dialogInterface.dismiss())
                .create();
        dialog.show();
    }

    protected void doFilterData() {

    }

    public void doFlushData() {
    }

    protected void doRollingGridView() {
    }

    private LinkedList<File> doGetUploadFiles() {
        String logPath = Environment.getExternalStorageDirectory().getAbsolutePath()
                + File.separator + "crash" + File.separator;
        File crashDir = new File(logPath);
        Date deleDate;
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE) - 1);
        String deleteDateString = myApplication.getSdfDate().format(calendar.getTime());
        try {
            deleDate = myApplication.getSdfDate().parse(deleteDateString);
        } catch (ParseException e) {
            deleDate = new Date();
            e.printStackTrace();
        }
        if (crashDir.isDirectory()) {
            File[] files = crashDir.listFiles();
            LinkedList<File> fileList = new LinkedList<>();
            for (File file : Objects.requireNonNull(files)
            ) {
                String fileName = file.getName();
                if (fileName.contains(".log") && fileName.startsWith("yfp-")) {
                    String fileDateString = fileName.substring(4, 14);
                    try {
                        Date fileDate = myApplication.getSdfDate().parse(fileDateString);
                        if (Objects.requireNonNull(fileDate).getTime() < Objects.requireNonNull(deleDate).getTime()) {
                            fileList.add(file);
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                }
            }
            return fileList;
        }
        return null;
    }

    public void doUploadLogFile() {
        final LinkedList<File> fileList = doGetUploadFiles();
        if (fileList != null && fileList.size() > 0) {
            if (!isUploading) {
                isUploading = true;
                ftpThread = new Thread(() -> {
                    while (isUploading) {
                        try {
                            new FtpUtil().uploadMultiFile(fileList, uploadListener, true);
                        } catch (IOException e) {
                            stopUploadThread();
                            KLog.d("APE", e.getMessage());
                            e.printStackTrace();
                        }
                    }
                });
                ftpThread.start();
            }
        } else {
            KLog.d("APE", "没有需要上传的日志！");
//            Toast.makeText(getApplicationContext(), "没有需要上传的日志！", Toast.LENGTH_SHORT).show();
        }
    }

    private void stopUploadThread() {
        isUploading = false;
        if (ftpThread != null && ftpThread.isAlive()) {
            ftpThread.interrupt();
            ftpThread = null;
        }
    }

    private final BroadcastReceiver SystemTimeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Objects.equals(intent.getAction(), Intent.ACTION_TIME_TICK)) {
                if (isTomorrow()) {
                    doSetQYSJ();
                }
                if (isRestartTime()) { //次日、11点 重启
                    new CountDownTimer(5000, 1000) {
                        @Override
                        public void onTick(long millisUntilFinished) {
                        }

                        @Override
                        public void onFinish() {
                            Intent intent1 = new Intent(getApplicationContext(), SplashActivity.class);
                            startActivity(intent1);
                        }
                    }.start();
                }
            }
        }
    };

    private boolean isRestartTime() {
        String timeNow = getMyApplication().getSdfTime().format(localDateTime);
        return timeNow.compareTo("23:59:55") > 0 || timeNow.compareTo("00:00:05") < 0 || (timeNow.compareTo("10:59:55") > 0 && timeNow.compareTo("11:00:05") < 0);
    }

    private boolean isTomorrow() {
        String timeNow = getMyApplication().getSdfTime().format(localDateTime);
        return timeNow.compareTo("10:59:55") > 0 && timeNow.compareTo("11:01:05") < 0 || timeNow.compareTo("23:59:55") > 0 || timeNow.compareTo("00:00:05") < 0;
    }

    public void doUpdateJHPB(final Patient patient) {
        Call<String> updateJHPBCall = MyServiceUtil.updateJHPBCall(patient.getCFHM());
        Callback<String> callback = new Callback<String>() {
            @Override
            public void onResponse(@NonNull Call<String> call, Response<String> response) {
                String result = response.body();
                if (result != null) {
                    result = result.substring(1, result.length() - 1);
                    if (result.startsWith("SUCCESS")) {
                        KLog.d("APE", "呼叫状态修改成功!");
                    } else {
                        KLog.d("APE", "呼叫状态修改失败!");
                    }
                }
            }

            @Override
            public void onFailure(@NonNull Call<String> call, Throwable t) {
                Toast.makeText(getApplicationContext(), patient.getPDHM() + "状态更新失败：" + t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        };
        updateJHPBCall.enqueue(callback);
    }

    protected void doUpdateXYJHPB(final HJBR hjbr) {
        Call<String> updateXYJHPBCall = MyServiceUtil.updateXYJHPB(hjbr.getCfsb());
        Callback<String> callback = new Callback<String>() {
            @Override
            public void onResponse(@NonNull Call<String> call, Response<String> response) {
                String result = response.body();
                if (result != null) {
                    result = result.substring(1, result.length() - 1);
                    if (result.startsWith("SUCCESS")) {
                        KLog.d("APE", "呼叫状态修改成功!");
                    } else {
                        KLog.d("APE", "呼叫状态修改失败!");
                    }
                }
            }

            @Override
            public void onFailure(@NonNull Call<String> call, Throwable t) {
                Toast.makeText(getApplicationContext(), hjbr.getPdhm() + "状态更新失败：" + t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        };
        updateXYJHPBCall.enqueue(callback);
    }

    public boolean isPassedPatient(String wcsj) {
        Calendar calendar = Calendar.getInstance();
        try {
            Date rightDate = getMyApplication().getSdfWeekDay().parse(showDate);
            calendar.setTime(Objects.requireNonNull(rightDate));
            int PASSED_MINUTE_TIME = 2;
            calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE) - PASSED_MINUTE_TIME, calendar.get(Calendar.SECOND));
            Date gsdate = calendar.getTime();
            Date wcdate = getMyApplication().getTsdfDateTime().parse(wcsj);
            return Objects.requireNonNull(wcdate).before(gsdate);
        } catch (ParseException e) {
            e.printStackTrace();
            return true;
        }
    }

    protected void rollingGridView(GridView gridView, int type) {
        List list;
        if (type == 1) {
            MyGridViewAdapter adapter = (MyGridViewAdapter) gridView.getAdapter();
            list = adapter.getPatientList();
        } else {
            MyHJBRAdapter adapter = (MyHJBRAdapter) gridView.getAdapter();
            list = adapter.getPatientList();
        }

        if (list != null && list.size() > 0) {
            int lastPos = gridView.getLastVisiblePosition();
            if (lastPos < list.size() - 1) {
                if (moveToBottom) {
                    moveToBottom = false;
                    gridView.smoothScrollToPosition(lastPos);
                } else {
                    moveToBottom = true;
                    gridView.smoothScrollToPosition(lastPos + 1);
                }
            } else {
                if (moveToBottom) {
                    gridView.smoothScrollToPosition(list.size() - 1);
                } else {
                    gridView.smoothScrollToPosition(1);
                }
                moveToBottom = !moveToBottom;
            }
        }
    }

}
